package com.zjpavt.client.page;

import com.zjpavt.client.command.InteractionCommandExecutor;
import com.zjpavt.client.hal.KeyPad;
import com.zjpavt.client.page.abstractpage.AbstractBasePage;
import com.zjpavt.client.page.intefacepage.BasePage;
import com.zjpavt.client.util.builderfactory.BuilderFactory;
import io.netty.util.concurrent.DefaultThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 页面统一管理类
 *
 * @author cjp
 */
public class PageManager implements AbstractBasePage.OnPageChangedListener {

    private static Logger log = LoggerFactory.getLogger(PageManager.class);

    private final static PageManager instance = new PageManager();
    private List<AbstractBasePage> pageList;
    private static final int PAGE_INDEX_INVALID = -1;
    private volatile int currPageNum = PAGE_INDEX_INVALID;
    public static final int REFRESH_PERIOD = 1000;

    private final DefaultThreadFactory pageManagerThreadFactory = new DefaultThreadFactory("PageManager");
    /**
     * 负责线程刷新的核心线程类
     */
    private ScheduledExecutorService autoRefreshTimer = new ScheduledThreadPoolExecutor(1, pageManagerThreadFactory);

    //用于填充界面布局的空格
    public static final String SPACE_FILL_1 = " ";
    private InteractionCommandPage interactionCommandPage;

    public static PageManager getInstance() {
        return instance;
    }

    private PageManager() {
        pageManagerThreadFactory.newThread(()-> {
            initPage();
            initListener();
            setPage(0);
            autoRefreshTimer.scheduleAtFixedRate(()->{
                getCurrentPage().startAutoRefreshing();
            }, REFRESH_PERIOD, REFRESH_PERIOD, TimeUnit.MILLISECONDS);
            log.info("pageManagerThreadFactory initial finished");
        }).start();
    }

    /**
     * todo 重构
     */
    private void initPage() {
        pageList = new ArrayList<>();
        pageList.add(BuilderFactory.bulid(new TimePage(pageList.size() + 1, 1000)));//1
        pageList.add(new SystemIdPage(pageList.size() + 1,4000));//2
        pageList.add(new NetStatusPage(pageList.size() + 1,1000));//3
        pageList.add(BuilderFactory.bulid(new LocationLuxPage(pageList.size() + 1,1000)));//4
        TemperaturePage temperaturePage = BuilderFactory.bulid(new TemperaturePage(pageList.size() + 1, 1000));
        pageList.add(temperaturePage);//5
        this.temperaturePage = temperaturePage;
        interactionCommandPage = new InteractionCommandPage(pageList.size() + 1,4000);
        pageList.add(interactionCommandPage);//6
        pageList.add(BuilderFactory.bulid(new OfflineCommandPage(pageList.size() + 1,4000)));//7
        pageList.add(BuilderFactory.bulid(new NextOfflineCommandPage(pageList.size() + 1,4000)));//8
        this.timerPage = BuilderFactory.bulid(new TimerPage(pageList.size() + 1,4000));
        pageList.add(timerPage);//9
        //pageList.add(BuilderFactory.bulid(new ChannelStatusPage(pageList.size() + 1,4000)));
        pageList.add(BuilderFactory.bulid(new NetworkModelPage(pageList.size() + 1,1000)));//10
        pageList.add(new ExtendAttributePage(pageList.size() + 1,4000));//11
        this.currentVoltagePage = BuilderFactory.bulid(new CurrentVoltagePage(pageList.size() + 1,4000));
        pageList.add(currentVoltagePage);//12
        pageList.add(BuilderFactory.bulid(new CurrentChannelStatePage(pageList.size() + 1,4000)));//13
        this.loopGroupControlPage = new LoopGroupControlPage(pageList.size() + 1, 1000);
        pageList.add(loopGroupControlPage);//14
        pageList.add(BuilderFactory.bulid(new ConfigPage(pageList.size() + 1,4000)));//15
        pageList.add(BuilderFactory.bulid(new VideoPage(pageList.size() + 1,4000)));//16

    }

    private CurrentVoltagePage currentVoltagePage;
    private LoopGroupControlPage loopGroupControlPage;
    private TimerPage timerPage;
    private TemperaturePage temperaturePage;

    public TemperaturePage getTemperaturePage() {
        return temperaturePage;
    }

    public void setTemperaturePage(TemperaturePage temperaturePage) {
        this.temperaturePage = temperaturePage;
    }

    public TimerPage getTimerPage() {
        return timerPage;
    }

    public void setTimerPage(TimerPage timerPage) {
        this.timerPage = timerPage;
    }

    public LoopGroupControlPage getLoopGroupControlPage() {
        return loopGroupControlPage;
    }

    public CurrentVoltagePage getCurrentVoltagePage() {
        return currentVoltagePage;
    }

    private void initListener() {
        KeyPad.getInstance().addKeyListener(keyCode -> pageList.get(currPageNum).onKeyPressed(keyCode));
        for (AbstractBasePage page : pageList) {
            page.setOnPageChangedListener(this);
        }
        InteractionCommandExecutor.getInstance().addListener(() -> {
            if (PageManager.getInstance().getCurrPageNum() == (interactionCommandPage.getPageNum() - 1)) {
                interactionCommandPage.refreshPage();
            }
        });
    }

    public void setPage(int pageIndex) {
        if (pageIndex >= pageList.size() || pageIndex < 0) {
            log.error("pageIndex out of size");
            return;
        }
        if (pageIndex == currPageNum) {
            pageList.get(currPageNum).refreshPage();
            log.error("already in this page");
            return;
        }
        if (currPageNum != PAGE_INDEX_INVALID) {
            pageList.get(currPageNum).onVisibleChanged(false);
        }
        currPageNum = pageIndex;
        pageList.get(currPageNum).onVisibleChanged(true);
    }

    /**
     *  第一页的currPageNum 从0开始
     * @return
     */
    public int getCurrPageNum() {
        return currPageNum;
    }

    /**
     * 返回当前页面
     * @return 返回当前页面
     */
    public BasePage getCurrentPage() {
        return pageList.get(currPageNum);
    }
    @Override
    public void onPageUp() {
        if (currPageNum == 0) {
            setPage(pageList.size() - 1);
            return;
        }
        setPage(currPageNum - 1);
    }

    @Override
    public void onPageDown() {
        if (currPageNum == pageList.size() - 1) {
            setPage(0);
            return;
        }
        setPage(currPageNum + 1);
    }
}
